﻿/*
 * Created by SharpDevelop.
 * Author: Taranu Bogdan
 * Date: 5/4/2012
 * Time: 3:02 PM
 */
using System;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Text;

namespace SensorClient
{
    /// <summary>
    /// Contains the sensors real values
    /// </summary>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/SensorContainer.xsd")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/SensorContainer.xsd", IsNullable = false)]
    public class SensorContainer
    {
        #region Constants
        /// <summary>
        /// Size of the real ECG vector
        /// </summary>
        public const int ECG_SIZE = 100;
        /// <summary>
        /// Size of the real HTA vector
        /// </summary>
        public const int HTA_SIZE = 2;
        /// <summary>
        /// The position where is placed the systolic HTA value 
        /// </summary>
        public const int HTA_SYSTOLIC = 0;
        /// <summary>
        /// The position where is placed the diastolic HTA value 
        /// </summary>
        public const int HTA_DIASTOLIC = 1;
        #endregion

        #region Members
        /// <summary>
        /// A vector containing the ECG real values
        /// </summary>
        private int[] ecg;
        /// <summary>
        /// A vector containing the 2 HTA real values (systolic and diastolic)
        /// </summary>
        private int[] hta;
        /// <summary>
        /// Contains the real value of the pulse
        /// </summary>
        private int pulse;
        /// <summary>
        /// Contains the real value of the body temperature
        /// </summary>
        private float bodyTemp;
        /// <summary>
        /// Contains the real value of the weight
        /// </summary>
        private float weight;
        /// <summary>
        /// Contains the real value of the glicemia
        /// </summary>
        private int glicemia;
        /// <summary>
        /// Contains the real value of the respiratory frequency
        /// </summary>
        private int respiratoryFrequency;
        /// <summary>
        /// Contains the real value of the ambient temperature
        /// </summary>
        private int ambientTemperature;
        /// <summary>
        /// The variable is set if there is not enough light in the room
        /// containing the Crossbow module.
        /// </summary>
        private bool notEnoughLight;
        /// <summary>
        /// The variable is set if there is a flood danger in the room
        /// containing the Crossbow module.
        /// </summary>
        private bool humidityDanger;
        /// <summary>
        /// The variable is set if there is the room containing the Crossbow
        /// module is empty
        /// </summary>
        private bool rfidEmptyRoom;
        /// <summary>
        /// The variable is set if there is no power in the room 
        /// containing the Crossbow module.
        /// </summary>
        private bool powerDown;
        /// <summary>
        /// The variable is set if there is gas leak in the room
        /// containing the Crossbow module
        /// </summary>
        private bool gasProblem;
        /// <summary>
        /// The id of the module sending the information
        /// </summary>
        private int moduleId;
        #endregion

        #region Constructors
        /// <summary>
        /// Dummy constructor for serialization
        /// </summary>
        public SensorContainer()
        {
            ecg = new int[ECG_SIZE];
            hta = new int[HTA_SIZE];
        }
        /// <summary>
        /// Creates a RealSensors object according to a existing
        /// data package (raw values of the sensors)
        /// </summary>
        /// <param name="package">The raw values of the sensors contained
        /// in a byte vector according to the PackageFormat</param>
        public SensorContainer(
                                     int moduleId,
                                     int[] ecg,
                                     int[] hta,
                                     int pulse,
                                     float bodyTemp,
                                     float weight,
                                     int glicemia,
                                     int respiratoryFrequency,
                                     int ambientTemperature,
                                     bool notEnoughLight,
                                     bool humidityDanger,
                                     bool rfidEmptyRoom,
                                     bool powerDown,
                                     bool gasProblem
                               )
        {
            this.moduleId = moduleId;
            this.ecg = new int[ECG_SIZE];
            this.hta = new int[HTA_SIZE];
            Array.Copy(ecg, this.ecg, ECG_SIZE);
            Array.Copy(hta, this.hta, HTA_SIZE);
            this.pulse = pulse;
            this.bodyTemp = bodyTemp;
            this.weight = weight;
            this.glicemia = glicemia;
            this.respiratoryFrequency = respiratoryFrequency;
            this.ambientTemperature = ambientTemperature;
            this.notEnoughLight = notEnoughLight;
            this.humidityDanger = humidityDanger;
            this.rfidEmptyRoom = rfidEmptyRoom;
            this.powerDown = powerDown;
            this.gasProblem = gasProblem;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Returns a reference to the ECG real values
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("Ecg")]
        public int[] Ecg
        {
            get
            {
                return ecg;
            }
            set
            {
                ecg = value;
            }
        }
        /// <summary>
        /// Returns the real value of systolic HTA
        /// </summary>
        public int HtaSystolic
        {
            get
            {
                return hta[HTA_SYSTOLIC];
            }
            set
            {
                hta[HTA_SYSTOLIC] = value;
            }
        }
        /// <summary>
        /// Returns the real value of diastolic HTA
        /// </summary>
        public int HtaDiastolic
        {
            get
            {
                return hta[HTA_DIASTOLIC];
            }
            set
            {
                hta[HTA_DIASTOLIC] = value;
            }
        }
        /// <summary>
        /// Returns the real value of pulse
        /// </summary>
        public int Pulse
        {
            get
            {
                return pulse;
            }
            set
            {
                pulse = value;
            }
        }
        /// <summary>
        /// Returns the real value of body temperature
        /// </summary>
        public float BodyTemperature
        {
            get
            {
                return bodyTemp;
            }
            set
            {
                bodyTemp = value;
            }
        }
        /// <summary>
        /// Returns the real value of glicemia
        /// </summary>
        public int Glicemia
        {
            get
            {
                return glicemia;
            }
            set
            {
                glicemia = value;
            }
        }
        /// <summary>
        /// Returns the real value of respiratory frequency
        /// </summary>
        public int RespiratoryFrequency
        {
            get
            {
                return respiratoryFrequency;
            }
            set
            {
                respiratoryFrequency = value;
            }
        }
        /// <summary>
        /// Returns true if there is not enough light in the room
        /// containing the Crossbow module. Otherwise returns false.
        /// </summary>
        public bool NotEnoughLight
        {
            get
            {
                return notEnoughLight;
            }
            set
            {
                notEnoughLight = value;
            }
        }
        /// <summary>
        /// Returns the real value of ambient temperature
        /// </summary>
        public int AmbientTemperature
        {
            get
            {
                return ambientTemperature;
            }
            set
            {
                ambientTemperature = value;
            }
        }
        /// <summary>
        /// Returns true if there is a gas leak in the room
        /// containing the Crossbow module. Otherwise returns false.
        /// </summary>
        public bool GasProblem
        {
            get
            {
                return gasProblem;
            }
            set
            {
                gasProblem = value;
            }
        }
        /// <summary>
        /// Indicates if there is or not a flood danger
        /// </summary>
        public bool HumidityDanger
        {
            get
            {
                return humidityDanger;
            }
            set
            {
                humidityDanger = value;
            }

        }
        /// <summary>
        /// Indicates if the followed persion is in the room or not
        /// </summary>
        public bool RfidEmptyRoom
        {
            get
            {
                return rfidEmptyRoom;
            }
            set
            {
                rfidEmptyRoom = value;
            }
        }
        /// <summary>
        /// Indicates if there is no power in the room
        /// </summary>
        public bool PowerDown
        {
            get
            {
                return powerDown;
            }
            set
            {
                powerDown = value;
            }
        }
        /// <summary>
        /// The id of the module sending the sensors raw information
        /// </summary>
        public int ModuleId
        {
            get { return moduleId; }
            set { moduleId = value; }
        }
        /// <summary>
        /// Weight of the pacient
        /// </summary>
        public float Weight
        {
            get { return weight; }
            set { weight = value; }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Creates a string containing all information about sensors
        /// </summary>
        /// <returns>A string containing all information about sensors</returns>
        public override string ToString()
        {
            string result = "";
            int i = 0;

            result += "ECG: ";
            for (i = 0; i < ECG_SIZE; i++)
            {
                result += Ecg[i] + " ";
            }
            result += "\n" +
                      "HTA: " +
                      "Systolic: " + hta[HTA_SYSTOLIC] +
                      " Diastolic: " + hta[HTA_DIASTOLIC] + "\n" +
                      "Pulse: " + pulse + "\n" +
                      "Body Temperature: " + bodyTemp + "\n" +
                      "Weight: " + Weight + "\n" +
                      "Glicemia: " + glicemia + "\n" +
                      "Respiratory frequency: " + respiratoryFrequency + "\n" +
                      "Ambient temperature: " + ambientTemperature + "\n" +
                      "Not enough light: " + notEnoughLight + "\n" +
                      "Flood: " + humidityDanger + "\n" +
                      "Room empty: " + rfidEmptyRoom + "\n" +
                      "Power down: " + powerDown + "\n" +
                      "Gas problem: " + gasProblem + "\n";
            return result;
        }
        /// <summary>
        /// Serializes the object in a XML file
        /// </summary>
        /// <param name="path">The path where the xml file is saved</param>
        public void SaveToXml(string path)
        {
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(SensorContainer));
                TextWriter tw = new StreamWriter(path);
                serializer.Serialize(tw, this);
                tw.Close();
            }
            catch (Exception ex)
            {
                Console.Write("Error saving: " + ex.Message);
            }
        }
        /// <summary>
        /// Creates a new SensorContainer object from an XML file
        /// </summary>
        /// <param name="path">The path to the xml file</param>
        /// <returns>A SensorContainer object or null if an exception triggered</returns>
        public SensorContainer LoadFromXml(string path)
        {
            try
            {
                SensorContainer sc = new SensorContainer();
                XmlSerializer serializer = new XmlSerializer(typeof(SensorContainer));
                TextReader tr = new StreamReader(path);
                sc = (SensorContainer)(serializer.Deserialize(tr));
                tr.Close();
                return sc;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Converts the object to an XML string
        /// </summary>
        /// <returns>The xml string</returns>
        public string GetXmlString()
        {
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(SensorContainer));

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
                settings.Indent = false;
                settings.OmitXmlDeclaration = false;

                using (StringWriter textWriter = new StringWriter())
                {
                    using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
                    {
                        serializer.Serialize(xmlWriter, this);
                    }
                    return textWriter.ToString();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Creates a SensorContainer object from a xml string
        /// </summary>
        /// <param name="xml">The xml string</param>
        /// <returns>A SensorContainer object</returns>
        public static SensorContainer FromXmlString(string xml)
        {
            if (string.IsNullOrEmpty(xml))
            {
                return null;
            }
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(SensorContainer));

                XmlReaderSettings settings = new XmlReaderSettings();
                // No settings need modifying here

                using (StringReader textReader = new StringReader(xml))
                {
                    using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
                    {
                        return (SensorContainer)serializer.Deserialize(xmlReader);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}